﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Threading;
using System.Net;
using Reticle.Core;

namespace Reticle
{
    public partial class GlobalSettings : Form
    {
        public string ProfileName { get; private set; }
        public string ConfigView { get; private set; }
        // the specified tabpage to open in config profile view
        public int ConfigTab { get; private set; }

        public GlobalSettings()
        {
            InitializeComponent();
        }

        // load to selected node key
        public GlobalSettings(string nodeKey)
        {
            InitializeComponent();
            ConfigView = nodeKey;

        }

        // load to selected node key and tabpage
        public GlobalSettings(string nodeKey, int tab)
        {
            InitializeComponent();
            ConfigView = nodeKey;
            ConfigTab = tab;

        }

        private void GlobalSettings_Load(object sender, EventArgs e)
        {
            ProfileName = "";
            loadChatEvents();
            loadSettings();

            //populateProducts();
            populateServers();

            loadNodes();

            // load the current selected profiles config (if selected)
            if (ConfigView != null)
            {
                treeSettings.SelectedNode = treeSettings.Nodes[0].Nodes[ConfigView];

                if (ConfigTab != -1)
                {
                    tabProfiles.SelectedIndex = ConfigTab;
                }
                // reset values for both events
                ConfigView = null;
                ConfigTab = -1;
            }
            else
            {
                treeSettings.SelectedNode = treeSettings.Nodes[0].Nodes[0];

                // set currently selected node color
                resetNodeColors();
                treeSettings.SelectedNode.ForeColor = Color.Blue;
            }
        }

        // reset all nodes forecolors
        private void resetNodeColors()
        {
            // get 1st level nodes
            foreach (TreeNode node in treeSettings.Nodes)
            {
                node.ForeColor = Color.Black;

                // get 2nd level nodes
                foreach (TreeNode childNode in node.Nodes)
                {
                    childNode.ForeColor = Color.Black;
                }
            }
        }

        private void loadNodes()
        {
            treeSettings.Nodes.Clear();
            TreeNode profiles = treeSettings.Nodes.Add("Profiles", "Profiles");

            foreach (KeyValuePair<string, string> pair in Profile.GetProfiles("file"))
            {
                profiles.Nodes.Add(pair.Key, pair.Key);
            }

            TreeNode settings = treeSettings.Nodes.Add("Settings", "Settings");

            settings.Nodes.Add("Chat Behavior", "Chat Behavior");
            settings.Nodes.Add("Notifications", "Notifications");
            settings.Nodes.Add("Hashes", "Hashes");

            TreeNode cdkeymanager = treeSettings.Nodes.Add("CDKeyManager", "CDKey Manager");

            treeSettings.ExpandAll();
        }
        private void loadChatEvents()
        {
            cmbChatEvent.Items.Add("Normal");
            cmbChatEvent.Items.Add("Slide Down");
            cmbChatEvent.Items.Add("Bounce");
            cmbChatEvent.Items.Add("Clip (Vertical)");
            cmbChatEvent.Items.Add("Clip (Horizontal)");
            cmbChatEvent.Items.Add("Drop (Up)");
            cmbChatEvent.Items.Add("Drop (Down)");
            cmbChatEvent.Items.Add("Drop (Left)");
            cmbChatEvent.Items.Add("Drop (Right)");
            cmbChatEvent.Items.Add("Fade");
            cmbChatEvent.Items.Add("Puff");
            cmbChatEvent.Items.Add("Pulsate");
            cmbChatEvent.Items.Add("Shake");
        }

        private void loadSettings()
        {
            string chatEvent = Program.Window.checkSetting("chatevent");

            switch (chatEvent)
            {
                case "addChat":
                    cmbChatEvent.Text = "Normal";
                    break;
                case "addChatSlide":
                    cmbChatEvent.Text = "Slide Down";
                    break;
                case "addChatBounce":
                    cmbChatEvent.Text = "Bounce";
                    break;
                case "addChatClipV":
                    cmbChatEvent.Text = "Clip (Vertical)";
                    break;
                case "addChatClipH":
                    cmbChatEvent.Text = "Clip (Horizontal)";
                    break;
                case "addChatDropU":
                    cmbChatEvent.Text = "Drop (Up)";
                    break;
                case "addChatDropD":
                    cmbChatEvent.Text = "Drop (Down)";
                    break;
                case "addChatDropL":
                    cmbChatEvent.Text = "Drop (Left)";
                    break;
                case "addChatDropR":
                    cmbChatEvent.Text = "Drop (Right)";
                    break;
                case "addChatFade":
                    cmbChatEvent.Text = "Fade";
                    break;
                case "addChatPuff":
                    cmbChatEvent.Text = "Puff";
                    break;
                case "addChatPulsate":
                    cmbChatEvent.Text = "Pulsate";
                    break;
                case "addChatShake":
                    cmbChatEvent.Text = "Shake";
                    break;
            }

            if (Program.Window.checkSetting("urllinks") == "1")
            {
                chkConvertURL.Checked = true;
            }
            else
            {
                chkConvertURL.Checked = false;
            }

            // Get the value for image embedding
            if (Program.Window.checkSetting("imagebot") == "1")
            {
                btnImageEmbedClick.BackColor = Color.LightGray;
            }
            else if (Program.Window.checkSetting("imageembed") == "1")
            {
                btnImageEmbedInstant.BackColor = Color.LightGray;
            }
            else if (Program.Window.checkSetting("imagebot") == "0" && Program.Window.checkSetting("imageembed") == "0")
            {
                btnImageEmbedNone.BackColor = Color.LightGray;
            }
            else
            {
                btnImageEmbedNone.BackColor = Color.LightGray;
            }

            // Get the value for video embedding
            if (Program.Window.checkSetting("youtubebot") == "1")
            {
                btnVideoEmbedClick.BackColor = Color.LightGray;
            }
            else if (Program.Window.checkSetting("youtubeembed") == "1")
            {
                btnVideoEmbedInstant.BackColor = Color.LightGray;
            }
            else if (Program.Window.checkSetting("youtubebot") == "0" && Program.Window.checkSetting("youtubeembed") == "0")
            {
                btnVideoEmbedNone.BackColor = Color.LightGray;
            }
            else
            {
                btnVideoEmbedNone.BackColor = Color.LightGray;
            }

            if (Program.Window.checkSetting("notifytalk") == "1")
            {
                chkNotifyNormal.Checked = true;
            }
            else
            {
                chkNotifyNormal.Checked = false;
            }

            if (Program.Window.checkSetting("notifyemote") == "1")
            {
                chkNotifyEmote.Checked = true;
            }
            else
            {
                chkNotifyEmote.Checked = false;
            }

            if (Program.Window.checkSetting("notifywhisper") == "1")
            {
                chkNotifyWhisper.Checked = true;
            }
            else
            {
                chkNotifyWhisper.Checked = false;
            }
        }

        private string convertChatEvent(string chatevent)
        {
            switch (chatevent)
            {
                case "Normal":
                    return "addChat";
                case "Slide Down":
                    return "addChatSlide";
                case "Bounce":
                    return "addChatBounce";
                case "Clip (Vertical)":
                    return "addChatClipV";
                case "Clip (Horizontal)":
                    return "addChatClipH";
                case "Drop (Up)":
                    return "addChatDropU";
                case "Drop (Down)":
                    return "addChatDropD";
                case "Drop (Left)":
                    return "addChatDropL";
                case "Drop (Right)":
                    return "addChatDropR";
                case "Fade":
                    return "addChatFade";
                case "Puff":
                    return "addChatPuff";
                case "Pulsate":
                    return "addChatPulsate";
                case "Shake":
                    return "addChatShake";
            }

            return "addChat";
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            XDocument doc = XDocument.Load(Application.StartupPath + @"\files\config.xml");

            foreach (XElement xe in doc.Descendants("Settings"))
            {
                xe.Element("chatevent").Value = convertChatEvent(cmbChatEvent.Text);

                if (chkConvertURL.Checked)
                {
                    xe.Element("urllinks").Value = "1";
                }
                else
                {
                    xe.Element("urllinks").Value = "0";
                }

                // Get values for image embedding
                if (btnImageEmbedClick.BackColor == Color.LightGray)
                {
                    xe.Element("imagebot").Value = "1";
                    xe.Element("imageembed").Value = "0";
                }
                else
                {
                    xe.Element("imagebot").Value = "0";
                }

                if (btnImageEmbedInstant.BackColor == Color.LightGray)
                {
                    xe.Element("imageembed").Value = "1";
                    xe.Element("imagebot").Value = "0";
                }
                else
                {
                    xe.Element("imageembed").Value = "0";
                }

                if (btnImageEmbedNone.BackColor == Color.LightGray)
                {
                    xe.Element("imagebot").Value = "0";
                    xe.Element("imageembed").Value = "0";
                }

                // Get values for video embedding
                if (btnVideoEmbedClick.BackColor == Color.LightGray)
                {
                    xe.Element("youtubebot").Value = "1";
                    xe.Element("youtubeembed").Value = "0";
                }
                else
                {
                    xe.Element("youtubebot").Value = "0";
                }

                if (btnVideoEmbedInstant.BackColor == Color.LightGray)
                {
                    xe.Element("youtubeembed").Value = "1";
                    xe.Element("youtubebot").Value = "0";
                }
                else
                {
                    xe.Element("youtubeembed").Value = "0";
                }

                if (btnVideoEmbedNone.BackColor == Color.LightGray)
                {
                    xe.Element("youtubebot").Value = "0";
                    xe.Element("youtubeembed").Value = "0";
                }

                if (chkNotifyNormal.Checked)
                {
                    xe.Element("notifytalk").Value = "1";
                }
                else
                {
                    xe.Element("notifytalk").Value = "0";
                }

                if (chkNotifyEmote.Checked)
                {
                    xe.Element("notifyemote").Value = "1";
                }
                else
                {
                    xe.Element("notifyemote").Value = "0";
                }

                if (chkNotifyWhisper.Checked)
                {
                    xe.Element("notifywhisper").Value = "1";
                }
                else
                {
                    xe.Element("notifywhisper").Value = "0";
                }
            }

            /*foreach (XElement xe in doc.Descendants("Verbytes"))
            {
                xe.Element("star").Value = txtVerbyteSTAR.Text;
                xe.Element("w2bn").Value = txtVerbyteW2BN.Text;
                xe.Element("d2dv").Value = txtVerbyteD2DV.Text;
                xe.Element("war3").Value = txtVerbyteWAR3.Text;
            }*/

            doc.Save(Application.StartupPath + @"\files\config.xml");

            if (ProfileName != "")
            {
                saveProfile(ProfileName);
            }

            // save CDKeys
            saveCDKeys();

            Program.Window.RefreshSettings();
            Close();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void treeSettings_AfterSelect(object sender, TreeViewEventArgs e)
        {
            // set currently selected node color
            resetNodeColors();
            e.Node.ForeColor = Color.Blue;

            if (e.Node.FullPath == @"Settings\Chat Behavior")
            {
                grpDefault.Visible = false;
                grpChatBehavior.Visible = true;
                grpNotifications.Visible = false;
                tabProfiles.Visible = false;
                grpHashes.Visible = false;
                grpCDKeys.Visible = false;
                profileButtons("hide");
            }
            else if (e.Node.FullPath == @"Settings\Notifications")
            {
                grpDefault.Visible = false;
                grpChatBehavior.Visible = false;
                grpNotifications.Visible = true;
                tabProfiles.Visible = false;
                grpHashes.Visible = false;
                grpCDKeys.Visible = false;
                profileButtons("hide");
            }
            else if (e.Node.FullPath == @"Settings\Hashes")
            {
                grpDefault.Visible = false;
                grpChatBehavior.Visible = false;
                grpNotifications.Visible = false;
                tabProfiles.Visible = false;
                grpHashes.Visible = true;
                grpCDKeys.Visible = false;

                checkHashes("all");
                profileButtons("hide");
            }
            else if (e.Node.FullPath == @"CDKey Manager")
            {
                grpDefault.Visible = false;
                grpChatBehavior.Visible = false;
                grpNotifications.Visible = false;
                tabProfiles.Visible = false;
                grpHashes.Visible = false;
                grpCDKeys.Visible = true;

                populateCDKeyProducts();
                profileButtons("hide");
            }
            else if (e.Node.FullPath.Contains(@"Profiles\"))
            {
                grpDefault.Visible = false;
                grpChatBehavior.Visible = false;
                grpNotifications.Visible = false;
                tabProfiles.Visible = true;
                grpHashes.Visible = false;
                grpCDKeys.Visible = false;

                loadProfile(e.Node.Text);
                profileButtons("show");
            }
            else
            {
                grpDefault.Visible = true;
                grpChatBehavior.Visible = false;
                grpNotifications.Visible = false;
                tabProfiles.Visible = false;
                grpHashes.Visible = false;
                grpCDKeys.Visible = false;

                profileButtons("hide");
            }
        }

        // show or hide teh profile buttons
        private void profileButtons(string hideshow)
        {
            switch (hideshow)
            {
                case "hide":
                    btnNewProfile.Visible = false;
                    btnDeleteProfile.Visible = false;
                    btnRenameProfile.Visible = false;
                    break;
                case "show":
                    btnNewProfile.Visible = true;
                    btnDeleteProfile.Visible = true;
                    btnRenameProfile.Visible = true;
                    break;
            }
        }

        private void checkHashes(string product)
        {
            switch(product)
            {
                //STAR/SEXP
                case "STAR":
                    if (Manager.CheckConfigHashes("STAR"))
                    {
                        lblSTARFound.Text = "Found";
                        lblSTARFound.ForeColor = Color.Green;
                        btnSTARDownload.Text = "ReDownload";
                    }
                    else
                    {
                        lblSTARFound.Text = "Not Found";
                        lblSTARFound.ForeColor = Color.Red;
                        btnSTARDownload.Text = "Download";
                    }
                    break;
                case "W2BN":
                    if (Manager.CheckConfigHashes("W2BN"))
                    {
                        lblW2BNFound.Text = "Found";
                        lblW2BNFound.ForeColor = Color.Green;
                        btnW2BNDownload.Text = "ReDownload";
                    }
                    else
                    {
                        lblW2BNFound.Text = "Not Found";
                        lblW2BNFound.ForeColor = Color.Red;
                        btnW2BNDownload.Text = "Download";
                    }
                    break;
                case "D2DV":
                    if (Manager.CheckConfigHashes("D2DV"))
                    {
                        lblD2DVFound.Text = "Found";
                        lblD2DVFound.ForeColor = Color.Green;
                        btnD2DVDownload.Text = "ReDownload";
                    }
                    else
                    {
                        lblD2DVFound.Text = "Not Found";
                        lblD2DVFound.ForeColor = Color.Red;
                        btnD2DVDownload.Text = "Download";
                    }
                    break;
                case "D2XP":
                    if (Manager.CheckConfigHashes("D2XP"))
                    {
                        lblD2XPFound.Text = "Found";
                        lblD2XPFound.ForeColor = Color.Green;
                        btnD2XPDownload.Text = "ReDownload";
                    }
                    else
                    {
                        lblD2XPFound.Text = "Not Found";
                        lblD2XPFound.ForeColor = Color.Red;
                        btnD2XPDownload.Text = "Download";
                    }
                    break;
                case "WAR3":
                    if (Manager.CheckConfigHashes("WAR3"))
                    {
                        lblWAR3Found.Text = "Found";
                        lblWAR3Found.ForeColor = Color.Green;
                        btnWAR3Download.Text = "ReDownload";
                    }
                    else
                    {
                        lblWAR3Found.Text = "Not Found";
                        lblWAR3Found.ForeColor = Color.Red;
                        btnWAR3Download.Text = "Download";
                    }
                    break;
                case "all":
                    checkHashes("STAR");
                    checkHashes("W2BN");
                    checkHashes("D2DV");
                    checkHashes("D2XP");
                    checkHashes("WAR3");
                    break;
            }
        }

        private string getVerbyte(string product)
        {
            Program.Window.RefreshSettings();

            switch (product)
            {
                case "STAR":
                case "SEXP":
                    return Program.Window.checkSetting("star-verbyte");
                case "W2BN":
                    return Program.Window.checkSetting("w2bn-verbyte");
                case "D2DV":
                case "D2XP":
                    return Program.Window.checkSetting("d2dv-verbyte");
                case "WAR3":
                case "W3XP":
                    return Program.Window.checkSetting("war3-verbyte");
            }

            return null;
        }

        private void loadProfile(string profile)
        {
            // Save previous profile
            if (ProfileName != "")
            {
                saveProfile(ProfileName);
            }

            ProfileName = treeSettings.SelectedNode.Text;
            
            Dictionary<string, string> d = Profile.GetSingleProfile(profile);
            //foreach (string key in d.Keys)
            //{
                txtUsername.Text = d["username"];
                txtPassword.Text = d["password"];
                cmbCDKeys.Text = d["cdkey"];
                cmbExpansion.Text = d["expansion"];
                //cmbProducts.Text = ConvertProduct(d["product"], "code");
                cmbServers.Text = d["server"];
                txtHomeChannel.Text = d["homechannel"];
                txtOrder.Text = d["order"];

                if (d["load"] == "1")
                {
                    chkLoadProfile.Checked = true;
                }
                else
                {
                    chkLoadProfile.Checked = false;
                }
            //}

            populateCDKeys(d["product"]);
            handleProduct(d["product"]);
            txtVerbyte.Text = getVerbyte(d["product"]);

            // handle the plugins
            PopulatePluginListBox(d["id"]);

            // get plugins available for download
            PopulateDownloadPlugins();
            
        }

        private void saveProfile(string name)
        {
            Dictionary<string, string> s = new Dictionary<string, string>();
            Dictionary<string, bool> plugins = new Dictionary<string, bool>();

            //if (checkConfig())
            //{
                s.Add("id", name);
                s.Add("username", txtUsername.Text);
                s.Add("password", txtPassword.Text);
                s.Add("cdkey", cmbCDKeys.Text);
                s.Add("expansion", cmbExpansion.Text);
                //s.Add("product", ConvertProduct(cmbProducts.Text, "string"));
                s.Add("product", saveProduct());
                s.Add("server", cmbServers.Text);
                s.Add("homechannel", txtHomeChannel.Text);
                s.Add("order", txtOrder.Text);
                s.Add("verbyte", txtVerbyte.Text);

                if (chkLoadProfile.Checked)
                {
                    s.Add("load", "1");
                }
                else
                {
                    s.Add("load", "0");
                }

                // Save Plugins
                foreach (object item in chkListPlugins.Items)
                {
                    if (chkListPlugins.GetItemCheckState(chkListPlugins.Items.IndexOf(item)).ToString() == "Checked")
                    {
                        plugins.Add(item.ToString(), true);
                    }
                    else
                    {
                        plugins.Add(item.ToString(), false);
                    }
                }

                // Save Profile
                Profile.SaveProfile(name, s, plugins);
            //}
        }

        private void renameProfile(string oldname, string newname)
        {
            Dictionary<string, string> s = new Dictionary<string, string>();
            Dictionary<string, bool> plugins = new Dictionary<string, bool>();

            //if (checkConfig())
            //{
                s.Add("id", newname);
                s.Add("username", txtUsername.Text);
                s.Add("password", txtPassword.Text);
                s.Add("cdkey", cmbCDKeys.Text);
                s.Add("expansion", cmbExpansion.Text);
                //s.Add("product", ConvertProduct(cmbProducts.Text, "string"));
                s.Add("product", saveProduct());
                s.Add("server", cmbServers.Text);
                s.Add("homechannel", txtHomeChannel.Text);
                s.Add("order", txtOrder.Text);
                s.Add("verbyte", txtVerbyte.Text);

                if (chkLoadProfile.Checked)
                {
                    s.Add("load", "1");
                }
                else
                {
                    s.Add("load", "0");
                }

                // Save Plugins
                foreach (object item in chkListPlugins.Items)
                {
                    if (chkListPlugins.GetItemCheckState(chkListPlugins.Items.IndexOf(item)).ToString() == "Checked")
                    {
                        plugins.Add(item.ToString(), true);
                    }
                    else
                    {
                        plugins.Add(item.ToString(), false);
                    }
                }

                Profile.SaveProfile(oldname, s, plugins);

                // set the new profile name so the user can save it
                ProfileName = newname;
            //}
        }

        // populate plugin list box to select which plugins to load on startup
        public void PopulatePluginListBox(string id)
        {
            // handle the plugins
            chkListPlugins.Items.Clear();

            List<string> plugins = PluginFunctions.GetAllPlugins();

            // get plugins from specific profiles config
            List<string> profilePlugins = Profile.GetPlugins(id);

            foreach (string plugin in plugins)
            {
                // if the plugin is already in the profile, check it by default
                if (profilePlugins.Contains(plugin))
                {
                    chkListPlugins.Items.Add(plugin, true);
                }
                else
                {
                    chkListPlugins.Items.Add(plugin);
                }
            }
        }

        // populate the dgvPlugins rows from the available plugins on the web
        public void PopulateDownloadPlugins()
        {
            // clear all items
            dgvPlugins.Rows.Clear();

            //XDocument doc = XDocument.Load("http://www.bnetweb.org/reticle/info.xml");
            XDocument doc = Manager.GetServerXML();

            foreach (XElement xe in doc.Descendants("plugin"))
            {
                dgvPlugins.Rows.Add(new object[] { xe.Element("name").Value, xe.Element("description").Value, "Get" });
            }
        }

        private void handleProduct(string product)
        {
            // reset colors from previous profile
            resetProduct();

            switch (product)
            {
                case "STAR":
                    btnSTAR.BackColor = Color.LightGray;
                    break;
                case "SEXP":
                    btnSEXP.BackColor = Color.LightGray;
                    break;
                case "W2BN":
                    btnW2BN.BackColor = Color.LightGray;
                    break;
                case "D2DV":
                    btnD2DV.BackColor = Color.LightGray;
                    break;
                case "D2XP":
                    btnD2XP.BackColor = Color.LightGray;
                    break;
                case "WAR3":
                    btnWAR3.BackColor = Color.LightGray;
                    break;
                case "W3XP":
                    btnW3XP.BackColor = Color.LightGray;
                    break;
            }
        }

        // reset colors from previous product
        private void resetProduct()
        {
            btnSTAR.BackColor = SystemColors.Control;
            btnSEXP.BackColor = SystemColors.Control;
            btnW2BN.BackColor = SystemColors.Control;
            btnD2DV.BackColor = SystemColors.Control;
            btnD2XP.BackColor = SystemColors.Control;
            btnWAR3.BackColor = SystemColors.Control;
            btnW3XP.BackColor = SystemColors.Control;
        }

        private bool checkConfig()
        {
            if (txtUsername.Text == "")
            {
                MessageBox.Show("Username cannot be empty.", "Username Required");
                return false;
            }
            if (txtPassword.Text == "")
            {
                MessageBox.Show("Password cannot be empty.", "Password Required");
                return false;
            }
            if (cmbCDKeys.Text == "")
            {
                MessageBox.Show("CDKey cannot be empty.", "CDKey Required");
                return false;
            }
            /*if (cmbProducts.Text == "")
            {
                MessageBox.Show("You must choose a product.", "Product Required");
                return false;
            }
            if ((ConvertProduct(cmbProducts.Text, "string") == "D2XP" && txtExpansion.Text == "") || (ConvertProduct(cmbProducts.Text, "string") == "W3XP" && txtExpansion.Text == ""))
            {
                MessageBox.Show("Expansion Key cannot be empty.", "Expansion Required");
                return false;
            }*/
            if (cmbServers.Text == "")
            {
                MessageBox.Show("Server cannot be empty.", "Server Required");
                return false;
            }
            if (txtHomeChannel.Text == "")
            {
                MessageBox.Show("Home Channel cannot be empty.", "Home Channel Required");
                return false;
            }
            if (txtOrder.Text == "")
            {
                txtOrder.Text = "99";
            }

            return true;
        }

        /*private void populateProducts()
        {
            cmbProducts.Items.Add("Starcraft");
            cmbProducts.Items.Add("Broodwar");
            cmbProducts.Items.Add("Warcraft II: BNE");
            cmbProducts.Items.Add("Diablo II");
            cmbProducts.Items.Add("Lord of Destruction");
            cmbProducts.Items.Add("Warcraft III");
            cmbProducts.Items.Add("The Frozen Throne");
        }*/

        private void populateServers()
        {
            cmbServers.Items.Add("useast.battle.net");
            cmbServers.Items.Add("63.240.202.126");
            cmbServers.Items.Add("63.240.202.127");
            cmbServers.Items.Add("63.240.202.128");
            cmbServers.Items.Add("63.240.202.129");
            cmbServers.Items.Add("63.240.202.130");
            cmbServers.Items.Add("63.240.202.131");
            cmbServers.Items.Add("63.240.202.134");
            cmbServers.Items.Add("63.240.202.138");
            cmbServers.Items.Add("63.240.202.139");
            cmbServers.Items.Add("63.240.202.120");
            cmbServers.Items.Add("63.240.202.121");
            cmbServers.Items.Add("63.240.202.122");
            cmbServers.Items.Add("");

            cmbServers.Items.Add("uswest.battle.net");
            cmbServers.Items.Add("63.241.83.7");
            cmbServers.Items.Add("63.241.83.8");
            cmbServers.Items.Add("63.241.83.9");
            cmbServers.Items.Add("63.241.83.11");
            cmbServers.Items.Add("63.241.83.12");
            cmbServers.Items.Add("63.241.83.13");
            cmbServers.Items.Add("63.241.83.107");
            cmbServers.Items.Add("63.241.83.108");
            cmbServers.Items.Add("63.241.83.109");
            cmbServers.Items.Add("63.241.83.110");
            cmbServers.Items.Add("63.241.83.111");
            cmbServers.Items.Add("63.241.83.112");
            cmbServers.Items.Add("");

            cmbServers.Items.Add("europe.battle.net");
            cmbServers.Items.Add("213.248.106.204");
            cmbServers.Items.Add("213.248.106.65");
            cmbServers.Items.Add("213.248.106.66");
            cmbServers.Items.Add("213.248.106.67");
            cmbServers.Items.Add("213.248.106.68");
            cmbServers.Items.Add("213.248.106.200");
            cmbServers.Items.Add("213.248.106.201");
            cmbServers.Items.Add("213.248.106.202");
            cmbServers.Items.Add("");

            cmbServers.Items.Add("asia.battle.net");
            cmbServers.Items.Add("211.233.0.74");
            cmbServers.Items.Add("211.233.0.75");
            cmbServers.Items.Add("211.233.0.76");
            cmbServers.Items.Add("211.233.0.78");
            cmbServers.Items.Add("211.233.0.79");
            cmbServers.Items.Add("211.233.0.80");
            cmbServers.Items.Add("211.233.0.49");
            cmbServers.Items.Add("211.233.0.50");
            cmbServers.Items.Add("211.233.0.51");
            cmbServers.Items.Add("211.233.0.52");
            cmbServers.Items.Add("211.233.0.53");
            cmbServers.Items.Add("211.233.0.54");
            cmbServers.Items.Add("211.233.0.55");
            cmbServers.Items.Add("211.233.0.56");
            cmbServers.Items.Add("211.233.0.57");
            cmbServers.Items.Add("211.233.0.58");
            cmbServers.Items.Add("211.233.0.59");
            cmbServers.Items.Add("211.233.0.60");
            cmbServers.Items.Add("211.233.0.61");
            cmbServers.Items.Add("211.233.0.62");
            cmbServers.Items.Add("211.233.0.63");
            cmbServers.Items.Add("211.233.0.64");
            cmbServers.Items.Add("211.233.0.72");
            cmbServers.Items.Add("211.233.0.73");
        }

        private void populateCDKeys(string product)
        {
            cmbCDKeys.Items.Clear();
            cmbExpansion.Items.Clear();
            switch(product)
            {
                case "STAR":
                case "SEXP":
                case "W2BN":
                case "D2DV":
                case "WAR3":
                    foreach (string key in CDKeyManager.LoadCDKeys(product))
                    {
                        cmbCDKeys.Items.Add(key);
                    }
                    break;
                case "D2XP":
                    foreach (string key in CDKeyManager.LoadCDKeys("D2DV"))
                    {
                        cmbCDKeys.Items.Add(key);
                    }
                    foreach (string key in CDKeyManager.LoadCDKeys(product))
                    {
                        cmbExpansion.Items.Add(key);
                    }
                    break;
                case "W3XP":
                    foreach (string key in CDKeyManager.LoadCDKeys("WAR3"))
                    {
                        cmbCDKeys.Items.Add(key);
                    }
                    foreach (string key in CDKeyManager.LoadCDKeys(product))
                    {
                        cmbExpansion.Items.Add(key);
                    }
                    break;
            }
        }

        public static string ConvertProduct(string product, string type)
        {
            if (type == "code")
            {
                switch (product.ToUpper())
                {
                    case "STAR":
                        return "Starcraft";
                    case "SEXP":
                        return "Broodwar";
                    case "W2BN":
                        return "Warcraft II: BNE";
                    case "D2DV":
                        return "Diablo II";
                    case "D2XP":
                        return "Lord of Destruction";
                    case "WAR3":
                        return "Warcraft III";
                    case "W3XP":
                        return "The Frozen Throne";
                }
            }
            else if (type == "string")
            {
                switch (product.ToLower())
                {
                    case "starcraft":
                        return "STAR";
                    case "broodwar":
                        return "SEXP";
                    case "warcraft ii: bne":
                        return "W2BN";
                    case "diablo ii":
                        return "D2DV";
                    case "lord of destruction":
                        return "D2XP";
                    case "warcraft iii":
                        return "WAR3";
                    case "the frozen throne":
                        return "W3XP";
                }
            }

            return null;
        }

        private void btnNewProfile_Click(object sender, EventArgs e)
        {
            string value = "";
            DialogResult x = InputBox("Add a Profile", "Name your profile", ref value);

            if (x == DialogResult.OK)
            {
                bool created = Profile.AddProfile(value);

                if (created)
                {
                    TreeNode node = treeSettings.Nodes["Profiles"];
                    node.Nodes.Add(value, value);
                }
            }
        }

        public static DialogResult InputBox(string title, string promptText, ref string value)
        {
            Form form = new Form();
            Label label = new Label();
            TextBox textBox = new TextBox();
            Button buttonOk = new Button();
            Button buttonCancel = new Button();

            form.Text = title;
            label.Text = promptText;
            textBox.Text = value;

            buttonOk.Text = "OK";
            buttonCancel.Text = "Cancel";
            buttonOk.DialogResult = DialogResult.OK;
            buttonCancel.DialogResult = DialogResult.Cancel;

            label.SetBounds(9, 15, 372, 13);
            textBox.SetBounds(12, 36, 372, 20);
            buttonOk.SetBounds(228, 72, 75, 23);
            buttonCancel.SetBounds(309, 72, 75, 23);

            label.AutoSize = true;
            textBox.Anchor = textBox.Anchor | AnchorStyles.Right;
            buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
            buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;

            form.ClientSize = new Size(396, 107);
            form.Controls.AddRange(new Control[] { label, textBox, buttonOk, buttonCancel });
            form.ClientSize = new Size(Math.Max(300, label.Right + 10), form.ClientSize.Height);
            form.FormBorderStyle = FormBorderStyle.FixedDialog;
            form.StartPosition = FormStartPosition.CenterScreen;
            form.MinimizeBox = false;
            form.MaximizeBox = false;
            form.AcceptButton = buttonOk;
            form.CancelButton = buttonCancel;

            DialogResult dialogResult = form.ShowDialog();
            value = textBox.Text;
            return dialogResult;
        }

        private void btnDeleteProfile_Click(object sender, EventArgs e)
        {
            string profile = treeSettings.SelectedNode.Text;
            DialogResult result = MessageBox.Show("Are you sure you want to remove '" + profile + "'?", "Delete Profile", MessageBoxButtons.YesNo);

            if (result == DialogResult.Yes)
            {
                Profile.RemoveProfile(profile);
            }

            loadNodes();
        }

        private void btnRenameProfile_Click(object sender, EventArgs e)
        {
            string value = "";
            DialogResult x = InputBox("Rename a Profile", "Rename your profile", ref value);

            if (x == DialogResult.OK && value != "")
            {
                bool alreadyExists = false;

                foreach (KeyValuePair<string, string> pair in Profile.GetProfiles("file"))
                {
                    if (pair.Key == value)
                    {
                        alreadyExists = true;
                    }
                }
                if (!alreadyExists)
                {
                    renameProfile(treeSettings.SelectedNode.Text, value);
                    loadNodes();
                }
                else
                {
                    MessageBox.Show("A profile by that name already exists.");
                }
            }
        }

        #region CDKeyManager
        public string CDKeyProduct = "";

        private void saveCDKeys()
        {
            if (CDKeyProduct != "")
            {
                List<string> keys = new List<string>();
                string product = ConvertProduct(CDKeyProduct, "string");

                foreach (string cdkey in txtCDKeys.Lines)
                {
                    if (cdkey != "")
                    {
                        keys.Add(cdkey.Trim());
                    }
                }

                CDKeyManager.SaveCDKeys(keys, product);
                loadCDKeys(ConvertProduct(cmbCDKeyProducts.Text, "string"));
            }
        }

        private void populateCDKeyProducts()
        {
            cmbCDKeyProducts.Items.Add("Starcraft");
            cmbCDKeyProducts.Items.Add("Broodwar");
            cmbCDKeyProducts.Items.Add("Warcraft II: BNE");
            cmbCDKeyProducts.Items.Add("Diablo II");
            cmbCDKeyProducts.Items.Add("Lord of Destruction");
            cmbCDKeyProducts.Items.Add("Warcraft III");
            cmbCDKeyProducts.Items.Add("The Frozen Throne");
        }

        private void cmbCDKeyProducts_SelectedIndexChanged(object sender, EventArgs e)
        {
            // save previously editted keys
            saveCDKeys();

            // load new keys
            loadCDKeys(ConvertProduct(cmbCDKeyProducts.Text, "string"));

            // re-enable the edit text box
            if (cmbCDKeyProducts.Text != "" && txtCDKeys.Enabled == false)
            {
                txtCDKeys.Enabled = true;
            }
            else if (cmbCDKeyProducts.Text == "")
            {
                txtCDKeys.Enabled = false;
            }

            // set current product
            CDKeyProduct = cmbCDKeyProducts.Text;
        }

        private void loadCDKeys(string product)
        {
            int count = 0;
            txtCDKeys.Clear();
            List<string> cdkeys = CDKeyManager.LoadCDKeys(product);

            foreach (string cdkey in cdkeys)
            {
                txtCDKeys.AppendText(cdkey + Environment.NewLine);
                count++;
            }

            lblCount.Text = "Keys: " + count.ToString();
        }

        #endregion

        // make sure they cannot download hashes at once (async not supported)
        // do this before the download begins
        private void handlePreDownload(string product)
        {
            switch (product)
            {
                case "STAR":
                    btnSTARDownload.Text = "Downloading...";
                    break;
                case "W2BN":
                    btnW2BNDownload.Text = "Downloading...";
                    break;
                case "D2DV":
                    btnD2DVDownload.Text = "Downloading...";
                    break;
                case "D2XP":
                    btnD2XPDownload.Text = "Downloading...";
                    break;
                case "WAR3":
                    btnWAR3Download.Text = "Downloading...";
                    break;
            }

            btnSTARDownload.Enabled = false;
            btnW2BNDownload.Enabled = false;
            btnD2DVDownload.Enabled = false;
            btnD2XPDownload.Enabled = false;
            btnWAR3Download.Enabled = false;
        }

        // make the buttons available to click again
        // do this after the download completes
        private void handlePostDownload()
        {
            btnSTARDownload.Enabled = true;
            btnW2BNDownload.Enabled = true;
            btnD2DVDownload.Enabled = true;
            btnD2XPDownload.Enabled = true;
            btnWAR3Download.Enabled = true;
        }

        private void btnSTARDownload_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(new ParameterizedThreadStart(DownloadHashes));
            thread.Start("STAR");

            handlePreDownload("STAR");
        }

        private void btnW2BNDownload_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(new ParameterizedThreadStart(DownloadHashes));
            thread.Start("W2BN");

            handlePreDownload("W2BN");
        }

        private void btnD2DVDownload_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(new ParameterizedThreadStart(DownloadHashes));
            thread.Start("D2DV");

            handlePreDownload("D2DV");
        }

        private void btnD2XPDownload_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(new ParameterizedThreadStart(DownloadHashes));
            thread.Start("D2XP");

            handlePreDownload("D2XP");
        }

        private void btnWAR3Download_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(new ParameterizedThreadStart(DownloadHashes));
            thread.Start("WAR3");

            handlePreDownload("WAR3");
        }

        public void DownloadHashes(object product)
        {
            //string product = "";
            WebClient webClient = new WebClient();

            if ((string)product != "")
            {
                switch ((string)product)
                {
                    case "STAR":
                    case "SEXP":
                        webClient.DownloadFile(new Uri("http://www.bnetweb.org/reticle/hashes/star/battle.snp"), Application.StartupPath + @"\files\hashes\STAR\Battle.snp");
                        webClient.DownloadFile(new Uri("http://www.bnetweb.org/reticle/hashes/star/starcraft.exe"), Application.StartupPath + @"\files\hashes\STAR\StarCraft.exe");
                        webClient.DownloadFile(new Uri("http://www.bnetweb.org/reticle/hashes/star/storm.dll"), Application.StartupPath + @"\files\hashes\STAR\Storm.dll");

                        if (InvokeRequired)
                        {
                            Invoke((MethodInvoker)delegate() { DownloadHashes(product); });
                        }
                        else
                        {
                            checkHashes("STAR");
                            handlePostDownload();
                        }
                        break;
                    case "W2BN":
                        webClient.DownloadFile(new Uri("http://www.bnetweb.org/reticle/hashes/w2bn/battle.snp"), Application.StartupPath + @"\files\hashes\W2BN\Battle.snp");
                        webClient.DownloadFile(new Uri("http://www.bnetweb.org/reticle/hashes/w2bn/warcraftiibne.exe"), Application.StartupPath + @"\files\hashes\W2BN\Warcraft II BNE.exe");
                        webClient.DownloadFile(new Uri("http://www.bnetweb.org/reticle/hashes/w2bn/storm.dll"), Application.StartupPath + @"\files\hashes\W2BN\Storm.dll");

                        if (InvokeRequired)
                        {
                            Invoke((MethodInvoker)delegate() { DownloadHashes(product); });
                        }
                        else
                        {
                            checkHashes("W2BN");
                            handlePostDownload();
                        }
                        break;
                    case "D2DV":
                        webClient.DownloadFile(new Uri("http://www.bnetweb.org/reticle/hashes/d2dv/bnclient.dll"), Application.StartupPath + @"\files\hashes\D2DV\Bnclient.dll");
                        webClient.DownloadFile(new Uri("http://www.bnetweb.org/reticle/hashes/d2dv/game.exe"), Application.StartupPath + @"\files\hashes\D2DV\Game.exe");
                        webClient.DownloadFile(new Uri("http://www.bnetweb.org/reticle/hashes/d2dv/d2client.dll"), Application.StartupPath + @"\files\hashes\D2DV\D2Client.dll");

                        if (InvokeRequired)
                        {
                            Invoke((MethodInvoker)delegate() { DownloadHashes(product); });
                        }
                        else
                        {
                            checkHashes("D2DV");
                            handlePostDownload();
                        }
                        break;
                    case "D2XP":
                        webClient.DownloadFile(new Uri("http://www.bnetweb.org/reticle/hashes/d2xp/bnclient.dll"), Application.StartupPath + @"\files\hashes\D2XP\Bnclient.dll");
                        webClient.DownloadFile(new Uri("http://www.bnetweb.org/reticle/hashes/d2xp/game.exe"), Application.StartupPath + @"\files\hashes\D2XP\Game.exe");
                        webClient.DownloadFile(new Uri("http://www.bnetweb.org/reticle/hashes/d2xp/d2client.dll"), Application.StartupPath + @"\files\hashes\D2XP\D2Client.dll");

                        if (InvokeRequired)
                        {
                            Invoke((MethodInvoker)delegate() { DownloadHashes(product); });
                        }
                        else
                        {
                            checkHashes("D2XP");
                            handlePostDownload();
                        }
                        break;
                    case "WAR3":
                    case "W3XP":
                        webClient.DownloadFile(new Uri("http://www.bnetweb.org/reticle/hashes/war3/game.dll"), Application.StartupPath + @"\files\hashes\WAR3\game.dll");
                        webClient.DownloadFile(new Uri("http://www.bnetweb.org/reticle/hashes/war3/war3.exe"), Application.StartupPath + @"\files\hashes\WAR3\war3.exe");
                        webClient.DownloadFile(new Uri("http://www.bnetweb.org/reticle/hashes/war3/storm.dll"), Application.StartupPath + @"\files\hashes\WAR3\Storm.dll");

                        if (InvokeRequired)
                        {
                            Invoke((MethodInvoker)delegate() { DownloadHashes(product); });
                        }
                        else
                        {
                            checkHashes("WAR3");
                            handlePostDownload();
                        }
                        break;
                }
            }
        }

        // Handle all click events for the product buttons
        private void btnProducts_Click(object sender, EventArgs e)
        {
            resetProduct();

            if (sender.Equals(btnSTAR))
            {
                btnSTAR.BackColor = Color.LightGray;
                populateCDKeys("STAR");
                txtVerbyte.Text = getVerbyte("STAR");
            }
            else if (sender.Equals(btnSEXP))
            {
                btnSEXP.BackColor = Color.LightGray;
                populateCDKeys("STAR");
                txtVerbyte.Text = getVerbyte("STAR");
            }
            else if (sender.Equals(btnW2BN))
            {
                btnW2BN.BackColor = Color.LightGray;
                populateCDKeys("W2BN");
                txtVerbyte.Text = getVerbyte("W2BN");
            }
            else if (sender.Equals(btnD2DV))
            {
                btnD2DV.BackColor = Color.LightGray;
                populateCDKeys("D2DV");
                txtVerbyte.Text = getVerbyte("D2DV");
            }
            else if (sender.Equals(btnD2XP))
            {
                btnD2XP.BackColor = Color.LightGray;
                populateCDKeys("D2XP");
                txtVerbyte.Text = getVerbyte("D2DV");
            }
            else if (sender.Equals(btnWAR3))
            {
                btnWAR3.BackColor = Color.LightGray;
                populateCDKeys("WAR3");
                txtVerbyte.Text = getVerbyte("WAR3");
            }
            else if (sender.Equals(btnW3XP))
            {
                btnW3XP.BackColor = Color.LightGray;
                populateCDKeys("W3XP");
                txtVerbyte.Text = getVerbyte("WAR3");
            }
        }

        // set the string for the selected product
        public string saveProduct()
        {
            if (btnSTAR.BackColor == Color.LightGray)
            {
                return "STAR";
            }
            else if (btnSEXP.BackColor == Color.LightGray)
            {
                return "SEXP";
            }
            else if (btnW2BN.BackColor == Color.LightGray)
            {
                return "W2BN";
            }
            else if (btnD2DV.BackColor == Color.LightGray)
            {
                return "D2DV";
            }
            else if (btnD2XP.BackColor == Color.LightGray)
            {
                return "D2XP";
            }
            else if (btnWAR3.BackColor == Color.LightGray)
            {
                return "WAR3";
            }
            else if (btnW3XP.BackColor == Color.LightGray)
            {
                return "W3XP";
            }

            return null;
        }

        // reset all chat behavior buttons colors (image)
        private void resetChatBehaviorImage()
        {
            btnImageEmbedClick.BackColor = SystemColors.Control;
            btnImageEmbedInstant.BackColor = SystemColors.Control;
            btnImageEmbedNone.BackColor = SystemColors.Control;
        }

        // reset all chat behavior buttons colors (video)
        private void resetChatBehaviorVideo()
        {
            btnVideoEmbedClick.BackColor = SystemColors.Control;
            btnVideoEmbedInstant.BackColor = SystemColors.Control;
            btnVideoEmbedNone.BackColor = SystemColors.Control;
        }

        // all the chat behavior (image) button click events
        private void btnChatBehaviorImage_Click(object sender, EventArgs e)
        {
            // reset all chat behavior buttons colors (image)
            resetChatBehaviorImage();

            if (sender.Equals(btnImageEmbedClick))
            {
                btnImageEmbedClick.BackColor = Color.LightGray;
            }
            else if (sender.Equals(btnImageEmbedInstant))
            {
                btnImageEmbedInstant.BackColor = Color.LightGray;
            }
            else if (sender.Equals(btnImageEmbedNone))
            {
                btnImageEmbedNone.BackColor = Color.LightGray;
            }
        }

        // all the chat behavior (video) button click events
        private void btnChatBehaviorVideo_Click(object sender, EventArgs e)
        {
            // reset all chat behavior buttons colors (video)
            resetChatBehaviorVideo();

            if (sender.Equals(btnVideoEmbedClick))
            {
                btnVideoEmbedClick.BackColor = Color.LightGray;
            }
            else if (sender.Equals(btnVideoEmbedInstant))
            {
                btnVideoEmbedInstant.BackColor = Color.LightGray;
            }
            else if (sender.Equals(btnVideoEmbedNone))
            {
                btnVideoEmbedNone.BackColor = Color.LightGray;
            }
        }

        // change password to hidden or not hidden
        private void chkShowPassword_CheckedChanged(object sender, EventArgs e)
        {
            if (chkShowPassword.Checked)
            {
                // show password
                txtPassword.PasswordChar = '\0';
            }
            else
            {
                // hide password
                txtPassword.PasswordChar = Convert.ToChar("*");
            }
        }

        private void dgvPlugins_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            // if user clicked "Get"
            if (e.ColumnIndex == 2)
            {
                string plugin = dgvPlugins[0, e.RowIndex].Value.ToString();

                //XDocument doc = XDocument.Load("http://www.bnetweb.org/reticle/info.xml");
                XDocument doc = Manager.GetServerXML();

                foreach (XElement xe in doc.Descendants("plugin"))
                {
                    if (xe.Element("name").Value == (string)plugin)
                    {
                        WebClient webClient = new WebClient();

                        webClient.DownloadFile(new Uri(String.Format("http://www.bnetweb.org/reticle/plugins/{0}", xe.Element("file").Value)), String.Format(@"{0}\files\plugins\{1}", Application.StartupPath, xe.Element("file").Value));

                        MessageBox.Show(String.Format("Successfully downloaded {0}!", xe.Element("name").Value));

                        PopulatePluginListBox(ProfileName);
                    }
                }
            }
        }

        private void GlobalSettings_Paint(object sender, PaintEventArgs e)
        {
            System.Drawing.Graphics graphicsObj;

            graphicsObj = tabProfile.CreateGraphics();

            Pen myPen = new Pen(Color.Black, 1.5F);
            Pen myPen2 = new Pen(Color.Black, 1);

            Brush myBrush = new SolidBrush(Color.Black);

            //graphicsObj.DrawLine(myPen, 432, 456, 43, 62);
            //graphicsObj.DrawLine(myPen2, 432, 456, 106, 125);
            //graphicsObj.DrawLine(myPen, 432, 456, 137, 156);

            graphicsObj.DrawLine(myPen, 432, 43, 456, 62);
            graphicsObj.DrawLine(myPen, 432, 106, 456, 125);
            graphicsObj.DrawLine(myPen, 432, 137, 456, 156);

        }
    }
}
